/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.base.controller;

import com.xy.biz.base.client.GoodsBatchClient;
import com.xy.biz.base.domain.converter.GoodsBatchConverter;
import com.xy.biz.base.domain.enums.GoodsBatchAuditStatusEnum;
import com.xy.biz.base.domain.enums.GoodsBatchStatusEnum;
import com.xy.biz.base.domain.query.GoodsBatchQuery;
import com.xy.biz.base.domain.req.*;
import com.xy.biz.base.domain.resp.GetGoodsBatchResponse;
import com.xy.biz.base.service.GoodsBatchService;
import com.xy.lang.domain.Page;
import com.xy.lang.domain.Result;
import com.xy.lang.util.EnumUtils;
import com.xy.lang.validation.SaveChecks;
import com.xy.lang.validation.UpdateChecks;
import com.xy.lang.validation.annotation.Validatable;
import com.xy.tool.util.BeanUtilsEx;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author zgy
 * @date 2021-9-22
 */
@Api(tags = "货品批次服务")
@Slf4j
@RestController
@RequestMapping("/api/base/goods_batch")
public class GoodsBatchController implements GoodsBatchClient {

    @Autowired
    private GoodsBatchService goodsBatchService;

    @Validatable(groups = {SaveChecks.class})
    @PostMapping(value = "/save")
    public Result<?> saveGoodsBatch(@RequestBody SaveGoodsBatchRequest request) {
        return goodsBatchService.saveGoodsBatch(GoodsBatchConverter.toBO(request));
    }

    @Validatable(groups = {SaveChecks.class})
    @PostMapping(value = "/save_all")
    public Result<?> saveAllGoodsBatch(@RequestBody Collection<SaveGoodsBatchRequest> collection) {
        return goodsBatchService.saveAllGoodsBatch(GoodsBatchConverter.toBO(collection));
    }

    @Validatable(groups = {UpdateChecks.class})
    @PostMapping(value = "/update")
    public Result<?> updateGoodsBatch(@RequestBody SaveGoodsBatchRequest request) {
        return goodsBatchService.updateGoodsBatch(GoodsBatchConverter.toBO(request));
    }

    @Validatable
    @PostMapping(value = "/delete")
    public Result<?> deleteGoodsBatch(@RequestBody GetGoodsBatchRequest request) {
        return goodsBatchService.deleteGoodsBatch(request.getGoodsBatchId());
    }

    @Validatable
    @PostMapping(value = "/get")
    @Override
    public Result<GetGoodsBatchResponse> getGoodsBatch(@RequestBody GetGoodsBatchRequest request) {
        return Result.success(GoodsBatchConverter.toResponse(goodsBatchService.getGoodsBatch(request.getGoodsBatchId())));
    }

    @PostMapping(value = "/list_by_ids")
    @Override
    public Result<List<GetGoodsBatchResponse>> listGoodsBatchById(@RequestBody Collection<Long> collection) {
        return Result.success(GoodsBatchConverter.toResponse(goodsBatchService.listGoodsBatchById(collection)));
    }

    @ApiOperation("根据货品Id获取批次的分组")
    @PostMapping(value = "/group_by_goods_id")
    @Override
    public Result<Map<Long, List<GetGoodsBatchResponse>>> groupGoodsBatchByGoodsId(@RequestBody Collection<Long> collection) {
        List<GetGoodsBatchResponse> goodsBatchList = GoodsBatchConverter.toResponse(
                goodsBatchService.listGoodsBatchByGoodsId(collection));
        if (CollectionUtils.isEmpty(goodsBatchList)) {
            return Result.success(Collections.emptyMap());
        }
        return Result.success(goodsBatchList.stream().collect(Collectors.groupingBy(GetGoodsBatchResponse::getGoodsId)));
    }

    @ApiOperation("根据货品Id获取批次列表")
    @PostMapping(value = "/list_by_single_goods_id")
    @Override
    public Result<List<GetGoodsBatchResponse>> listGoodsBatchBySingleGoodsId(@RequestBody GetGoodsRequest request) {
        return Result.success(GoodsBatchConverter.toResponse(
                goodsBatchService.listGoodsBatchByGoodsId(Arrays.asList(request.getGoodsId()))));
    }

    @ApiOperation("根据货号获取批次的分组")
    @PostMapping(value = "/group_by_goods_code")
    @Override
    public Result<Map<String, List<GetGoodsBatchResponse>>> groupGoodsBatchByGoodsCode(@RequestBody Collection<String> collection) {
        List<GetGoodsBatchResponse> goodsBatchList = GoodsBatchConverter.toResponse(
                goodsBatchService.listGoodsBatchByGoodsCode(collection));
        if (CollectionUtils.isEmpty(goodsBatchList)) {
            return Result.success(Collections.emptyMap());
        }
        return Result.success(goodsBatchList.stream().collect(Collectors.groupingBy(GetGoodsBatchResponse::getGoodsCode)));
    }

    @ApiOperation("根据货号获取批次列表")
    @PostMapping(value = "/list_by_single_goods_code")
    @Override
    public Result<List<GetGoodsBatchResponse>> listGoodsBatchBySingleGoodsCode(@RequestBody ListGoodsByCodeRequest request) {
        return Result.success(GoodsBatchConverter.toResponse(
                goodsBatchService.listGoodsBatchByGoodsCode(Arrays.asList(request.getGoodsCode()))));
    }

    @ApiOperation("根据货品（货品Id或货号）和批号的组合来查询")
    @PostMapping(value = "/list_by_goods_and_batch")
    @Override
    public Result<List<GetGoodsBatchResponse>> listGoodsBatchByGoodsAndBatch(@RequestBody Collection<GetGoodsBatchByGoodsAndBatchRequest> requestCollection) {
        return Result.success(GoodsBatchConverter.toResponse(
                goodsBatchService.listGoodsBatchByGoodsAndBatch(
                        BeanUtilsEx.copyPropertiesForNewList(requestCollection, () -> new GoodsBatchQuery(0)))));
    }

    @PostMapping(value = "/list")
    @Override
    public Result<List<GetGoodsBatchResponse>> listGoodsBatch(@RequestBody ListGoodsBatchRequest request) {
        return Result.success(GoodsBatchConverter.toResponse(goodsBatchService.listGoodsBatch(GoodsBatchConverter.toQuery(request))));
    }

    @PostMapping(value = "/page")
    @Override
    public Result<Page<GetGoodsBatchResponse>> pageGoodsBatch(@RequestBody ListGoodsBatchRequest request) {
        GoodsBatchQuery query = GoodsBatchConverter.toQuery(request);
        List<GetGoodsBatchResponse> list = GoodsBatchConverter.toResponse(goodsBatchService.listGoodsBatch(query));
        int count = goodsBatchService.countGoodsBatch(query);
        return Result.success(new Page<>(list, count));
    }

    @GetMapping(value = "/list_pre_options")
    public Result<Map<String, List>> listPreOptions() {
        Map<String, List> map = new HashMap<>();
        map.put("status", EnumUtils.toKeyValueList(GoodsBatchStatusEnum.values(), e -> ((GoodsBatchStatusEnum)e).getName()));
        map.put("auditStatus", EnumUtils.toKeyValueList(GoodsBatchAuditStatusEnum.values(), e -> ((GoodsBatchAuditStatusEnum)e).getName()));
        return Result.success(map);
    }

}
